#include "XmlInfoContrat.hpp"

#include "Core/StructureDonnees.hpp"

#include <QtCore/QStringList>

#include <QtCore/QDebug>

#include "Utils/Callback.hpp"

#include <iostream>

using namespace std;

XmlInfoContrat XmlInfoContrat::creeInstance(  const QString& nomFichier,
					      const QHash< QString,
                                              QString >* infos )
{
    QStringList elementsRecuperables;
    elementsRecuperables << "id" << "age" << "name" << "sex" << "city"
                         << "country" << "timezone" << "countdown"
                         << "prize" << "sadism" << "ugliness" << "power"
                         << "greediness" << "difficulty" << "accepted"
                         << "monster" << "kind" << "prize";
    QStringList elementsRecuperes;

    foreach ( QString tmp, elementsRecuperables )
        elementsRecuperes << (*infos)[ tmp ];

    XmlInfoContrat retour;

    // Récupération des infos obligatoires :
    if ( ! appelleSetUnsigned( elementsRecuperes[ 0 ],
                               &XmlInfoIdentifiant::setIdentification,
                               static_cast< XmlInfoIdentifiant* >( &retour ),
                               elementsRecuperables[ 0 ] ) )
        return XmlInfoContrat();

    retour . setNom( elementsRecuperes[ 2 ] );

    if ( ! appelleSetUnsigned( elementsRecuperes[ 9 ],
                               &XmlInfoCaracteristiques::setSadisme,
                               static_cast< XmlInfoCaracteristiques* >( &retour),
                               elementsRecuperables[ 9 ] ) )
        return XmlInfoContrat();
    if ( ! appelleSetUnsigned( elementsRecuperes[ 10 ],
                               &XmlInfoCaracteristiques::setLaideur,
                               static_cast< XmlInfoCaracteristiques* >( &retour),
                               elementsRecuperables[ 10 ] ) )
        return XmlInfoContrat();
    if ( ! appelleSetUnsigned( elementsRecuperes[ 11 ],
                               &XmlInfoCaracteristiques::setForce,
                               static_cast< XmlInfoCaracteristiques* >( &retour),
                               elementsRecuperables[ 11 ] ) )
        return XmlInfoContrat();
    if ( ! appelleSetUnsigned( elementsRecuperes[ 12 ],
                               &XmlInfoCaracteristiques::setGourmandise,
                               static_cast< XmlInfoCaracteristiques* >( &retour),
                               elementsRecuperables[ 12 ] ) )
        return XmlInfoContrat();

    if ( ! appelleSetUnsigned( elementsRecuperes[ 1 ],
                               &XmlInfoContrat::setAge,
                               static_cast< XmlInfoContrat* >( &retour),
                               elementsRecuperables[ 1 ] ) )
        return XmlInfoContrat();

    if ( ! appelleSetUnsigned( elementsRecuperes[ 3 ],
                               &XmlInfoContrat::setSexe,
                               static_cast< XmlInfoContrat* >( &retour ),
                               elementsRecuperables[ 3 ] ) )
        return XmlInfoContrat();

    retour . setVille( elementsRecuperes[ 4 ] );
    retour . setPays( elementsRecuperes[ 5 ] );

    if ( ! appelleSetInt( elementsRecuperes[ 6 ],
                          &XmlInfoContrat::setFuseauHoraire,
                          static_cast< XmlInfoContrat* >( &retour ),
                          elementsRecuperables[ 6 ] ) )
        return XmlInfoContrat();

    if ( ! appelleSetUnsigned( elementsRecuperes[ 7 ],
                               &XmlInfoContrat::setSecondesRestantes,
                               static_cast< XmlInfoContrat* >( &retour ),
                               elementsRecuperables[ 7 ] ) )
        return XmlInfoContrat();

    if ( ! appelleSetUnsigned( elementsRecuperes[ 16 ],
                               &XmlInfoContrat::setTypeContrat,
                               &retour,
                               elementsRecuperables[ 16 ] ) )
        return XmlInfoContrat();

    if ( ! appelleSetUnsigned( elementsRecuperes[ 17 ],
                               &XmlInfoContrat::setRecompense,
                               static_cast< XmlInfoContrat* >( &retour ),
                               elementsRecuperables[ 17 ] ) )
        return XmlInfoContrat();

    if ( ! appelleSetUnsigned( elementsRecuperes[ 13 ],
                               &XmlInfoContrat::setDifficulte,
                               static_cast< XmlInfoContrat* >( &retour ),
                               elementsRecuperables[ 13 ] ) )
        return XmlInfoContrat();

    retour . setNomFichier( nomFichier );

    return retour;
}

XmlInfoContrat::XmlInfoContrat()
    : XmlInfoCaracteristiques( "", 0, "", 0, 0, 0, 0 ),
      Age( 0u ), Sexe( 0u ), Ville( "" ), Pays( "" ),
      FuseauHoraire( 0 ), SecondesRestantes( 0u ),
      Recompense( 0u ), Difficulte( 0u ),
      Accepte( false ), IdMonstre( 0u )
{}

XmlInfoContrat::XmlInfoContrat( const QString& nomFichier,
				const unsigned& id,
				const QString& nom,
				const unsigned& sadisme,
				const unsigned& laideur,
				const unsigned& force,
				const unsigned& gourmandise,
				const unsigned& age,
				const unsigned sexe,
				const QString& ville,
				const QString& pays,
				const int& fuseauHoraire,
				const unsigned& secondesRestantes,
                                const EnumTypeContrat& typeContrat,
				const unsigned& recompense,
				const unsigned& difficulte )
    : XmlInfoCaracteristiques( nomFichier, id, nom, sadisme, laideur, force,
          gourmandise ),
      Age( age ), Sexe( sexe ), Ville( ville ), Pays( pays ),
      FuseauHoraire( fuseauHoraire ), SecondesRestantes( secondesRestantes ),
      TypeContrat( typeContrat ),
      Recompense( recompense ), Difficulte( difficulte ),
      Accepte( false ), IdMonstre( 0 )
{}

XmlInfoContrat::XmlInfoContrat( const XmlInfoContrat& contrat )
    : XmlInfoCaracteristiques( contrat ),
      Age( contrat.age() ),
      Sexe( contrat.sexe() ),
      Ville( contrat.ville() ),
      Pays( contrat.pays() ),
      FuseauHoraire( contrat.fuseauHoraire() ),
      SecondesRestantes( contrat.secondesRestantes() ),
      TypeContrat( contrat.typeContrat() ),
      Recompense( contrat.recompense() ),
      Difficulte( contrat.difficulte() ),
      Accepte( contrat.accepte() ),
      IdMonstre( contrat.idMonstre() )
{}

XmlInfoContrat::~XmlInfoContrat()
{}

XmlInfoContrat& XmlInfoContrat::operator=( const XmlInfoContrat& contrat )
{
    if ( &contrat != this )
    {
        this -> XmlInfoCaracteristiques::operator=( contrat );

        Age               = contrat.age();
        Sexe              = contrat.sexe();
        Ville             = contrat.ville();
        Pays              = contrat.pays();
        FuseauHoraire     = contrat.fuseauHoraire();
        SecondesRestantes = contrat.secondesRestantes();
        Recompense        = contrat.recompense();
        Difficulte        = contrat.difficulte();
        Accepte           = contrat.accepte();
        IdMonstre         = contrat.idMonstre();
    }

    return *this;
}

void XmlInfoContrat::afficheInstance() const
{
    qDebug() << QObject::trUtf8( "Nom de l'enfant : %1 (%2)." ).arg( nom() ).arg( sexe() == 0 ? "garçon" : "fille" );
    qDebug() << QObject::trUtf8( "Age de l'enfant : %1 ans." ).arg( age() );
    qDebug() << QObject::trUtf8( "Lieu : %1, %2 (fuseau %3)." ).arg( ville() ).arg( pays() ).arg( fuseauHoraire() );
    qDebug() << QObject::trUtf8( "Temps avant exécution : %1 s." ).arg( secondesRestantes() );
    qDebug() << QObject::trUtf8( "Type de contrat : %1." ).arg( static_cast< unsigned >( typeContrat() ) );
    qDebug() << QObject::trUtf8( "Nécéssite Sadisme = %1, Laideur = %2, Force = %3, Gourmandise = %4" ).arg( sadisme() ).arg( laideur() ).arg( force() ).arg( gourmandise() );
    qDebug() << QObject::trUtf8( "Récompense : %1." ).arg( recompense() );
    qDebug() << QObject::trUtf8( "Difficulté : %1." ).arg( difficulte() );
    if ( accepte() )
        qDebug() << QObject::trUtf8( "Id monstre en charge : %1." ).arg( idMonstre() );
}

const unsigned& XmlInfoContrat::caracteristique( const EnumCaracteristique &car ) const
{
    switch ( car )
    {
    case CarSadisme:
    case CarLaideur:
    case CarForce:
    case CarGourmandise:
        return XmlInfoCaracteristiques::caracteristique( car );
    case CarDifficulte:
        return difficulte();
    default:
        return typeContrat();
    }
}

const unsigned& XmlInfoContrat::caracteristique( const unsigned &car ) const
{
    return caracteristique( static_cast< EnumCaracteristique >( car % 7 ) );
}

const unsigned& XmlInfoContrat::age() const
{
    return Age;
}

const unsigned& XmlInfoContrat::sexe() const
{
    return Sexe;
}

const QString& XmlInfoContrat::ville() const
{
    return Ville;
}

const QString& XmlInfoContrat::pays() const
{
    return Pays;
}

const int& XmlInfoContrat::fuseauHoraire() const
{
    return FuseauHoraire;
}

const EnumTypeContrat& XmlInfoContrat::typeContrat() const
{
    return TypeContrat;
}

unsigned XmlInfoContrat::nbrCompetencesRequises() const
{
    if ( typeContrat() != Infernal )
        return static_cast< unsigned >( typeContrat() );
    else
        return 4;
}

const unsigned& XmlInfoContrat::secondesRestantes() const
{
    return SecondesRestantes;
}

const unsigned& XmlInfoContrat::recompense() const
{
    return Recompense;
}

const unsigned& XmlInfoContrat::difficulte() const
{
    return Difficulte;
}

const bool& XmlInfoContrat::accepte() const
{
    return Accepte;
}

const unsigned& XmlInfoContrat::idMonstre() const
{
    return IdMonstre;
}

void XmlInfoContrat::setAge( const unsigned& age )
{
    Age = age;
}

void XmlInfoContrat::setSexe( const unsigned& sexe )
{
    Sexe = sexe;
}

void XmlInfoContrat::setVille( const QString& ville )
{
    Ville = ville;
}

void XmlInfoContrat::setPays( const QString& pays )
{
    Pays = pays;
}

void XmlInfoContrat::setFuseauHoraire( const int& fuseauHoraire )
{
    FuseauHoraire = fuseauHoraire;
}

void XmlInfoContrat::setTypeContrat( const EnumTypeContrat& typeContrat )
{
    TypeContrat = typeContrat;
}

void XmlInfoContrat::setTypeContrat( const unsigned& typeContrat )
{
    setTypeContrat( static_cast< EnumTypeContrat >( typeContrat % 6 ) );
}

void XmlInfoContrat::setSecondesRestantes( const unsigned& secondesRestantes )
{
    SecondesRestantes = secondesRestantes;
}

void XmlInfoContrat::setRecompense( const unsigned& recompense )
{
    Recompense = recompense;
}

void XmlInfoContrat::setDifficulte( const unsigned& difficulte )
{
    Difficulte = difficulte;
}

void XmlInfoContrat::setIdMonstre( const unsigned& idMonstre )
{
    IdMonstre = idMonstre;

    Accepte = true;
}
